home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / TPLY30.ARJ / TP4.Y < prev    next >
Text File  |  1991-05-02  |  11KB  |  614 lines

  1.  
  2. /* Turbo Pascal 4.0 grammar (prototype) 5-1-91 AG
  3.  
  4.    This is an "almost complete" TP Yacc grammar for Turbo Pascal Version
  5.    4.0. Although the grammar is incomplete, untested and I do not have a
  6.    lexical analyzer for it yet, I decided to include it in the distribution
  7.    for those of you who are planning to write a Turbo Pascal parser.
  8.  
  9.    You will notice that this is not an adaption of the Standard Pascal
  10.    grammar in PAS.Y. Because of the many additional features in the
  11.    Turbo Pascal language I decided to write a new grammar from scratch.
  12.  
  13.    Writing a Yacc grammar for Turbo Pascal is not as easy as it first
  14.    seems to be, because the special language features often defy easy
  15.    specification as an LALR(1) grammar. Taking the naive approach, you
  16.    are bound to get a lot of parsing conflicts in your grammar, since
  17.    some of the constructs just cannot be parsed unambigiously without
  18.    making use of semantic information.
  19.  
  20.    One construct that causes trouble is the qualified identifier which,
  21.    in many contexts, can also be interpreted as a record component
  22.    designator. To fix this, I simply decided to treat both "ordinary" and
  23.    qualified identifiers as a single ID token. Of course this means that
  24.    the lexical analyzer will have to distinguish between ordinary and
  25.    qualified identifiers (this can be done with some semantic processing
  26.    to determine which identifiers are unit names).
  27.  
  28.    There is still one ambiguity left in the grammar (causing one shift/
  29.    reduce conflict) which comes from type casts in variable designators.
  30.    The construct in question has the form:
  31.  
  32.       ID ( variable )
  33.  
  34.    In certain contexts, this can both be interpreted as a variable and
  35.    as a function or procedure call. At present, the generated parser
  36.    will parse such a construct as a variable. This will not be any
  37.    problem (at least I hope so) unless you actually do semantic processing
  38.    in your parser.
  39.  
  40.    If you have any questions/comments/critizism concerning this grammar,
  41.    direct them to Graef@DMZRZU71 on bitnet. Perhaps someone even extends
  42.    the grammar towards Turbo Pascal 5.x/6.x (if you do, it would be kind
  43.    if you let me have a copy of this grammar such that I can include it in
  44.    the next distribution). */
  45.  
  46.  
  47. %start compilation_unit
  48.  
  49. /* Lexical stuff: */
  50.  
  51. %token
  52.  
  53. /* The multiple character symbols below are used in the grammar for better
  54.    readability; identifier synonyms are given for use in the lexical analyzer.
  55.    These definitions must come before any other token definitions (note that
  56.    TP Yacc starts counting user-defined literals at 257). */
  57.  
  58. '..' 257
  59. ':=' 258
  60. '<=' 259
  61. '<>' 260
  62. '>=' 261
  63.  
  64. %{
  65.  
  66. const
  67.  
  68. DOTDOT = 257
  69. DEFEQ  = 258
  70. LEQ    = 259
  71. NEQ    = 260
  72. GEQ    = 261
  73.  
  74. %}
  75.  
  76. %token
  77.  
  78. /* Keywords are stropped with underscores to prevent conflicts with Turbo
  79.    Pascal keywords. */
  80.  
  81. _AND_        _ABSOLUTE_    _ARRAY_            _BEGIN_
  82. _CASE_        _CONST_        _DIV_            _DOWNTO_
  83. _DO_        _ELSE_        _END_            _EXTERNAL_
  84. _FILE_        _FORWARD_    _FOR_            _FUNCTION_
  85. _GOTO_        _IF_        _IMPLEMENTATION_     _INTERFACE_
  86. _IN_        _LABEL_        _MOD_            _NIL_
  87. _NOT_        _OF_        _OR_            _PACKED_
  88. _PROCEDURE_    _PROGRAM_    _RECORD_        _REPEAT_
  89. _SET_        _SHL_        _SHR_            _STRING_
  90. _THEN_        _TO_        _TYPE_            _UNIT_
  91. _UNTIL_        _USES_        _VAR_            _WHILE_
  92. _WITH_        _XOR_
  93.  
  94. %right _THEN_ _ELSE_            /* resolve dangling else */
  95.  
  96. %token
  97.  
  98. ID
  99. UNSIGNED_INTEGER
  100. UNSIGNED_REAL
  101. STRING_CONST
  102.  
  103. %%
  104.  
  105. compilation_unit
  106.     : program
  107.         | unit
  108.         ;
  109.  
  110. /* Programs: */
  111.  
  112. program    : program_heading uses_clause block '.'
  113.     ;
  114.  
  115. program_heading
  116.     : /* empty */
  117.         | _PROGRAM_ ID ';'
  118.         | _PROGRAM_ ID '(' id_list ')' ';'
  119.     ;
  120.  
  121. uses_clause
  122.     : /* empty */
  123.         | _USES_ id_list ';'
  124.         ;
  125.  
  126. id_list    : ID
  127.     | id_list ',' ID
  128.         ;
  129.  
  130. block    : decl_sect_list compound_stmt
  131.     ;
  132.  
  133. /* Units: */
  134.  
  135. unit    : unit_heading interface_part implementation_part
  136.       initialization_part '.'
  137.     ;
  138.  
  139. unit_heading
  140.     : _UNIT_ ID ';'
  141.     ;
  142.  
  143. interface_part
  144.     : _INTERFACE_ uses_clause int_decl_sect_list
  145.         ;
  146.  
  147. implementation_part
  148.     : _IMPLEMENTATION_ decl_sect_list
  149.         ;
  150.  
  151. initialization_part
  152.     : compound_stmt
  153.         | _END_
  154.         ;
  155.  
  156. /* Declaration sections: */
  157.  
  158. decl_sect_list
  159.     : /* empty */
  160.         | decl_sect_list decl_sect
  161.         ;
  162.  
  163. decl_sect
  164.     : label_decl_sect
  165.     | const_decl_sect
  166.     | type_decl_sect
  167.     | var_decl_sect
  168.     | proc_decl
  169.     | func_decl
  170.     ;
  171.  
  172. label_decl_sect
  173.     : _LABEL_ label_list ';'
  174.     ;
  175.  
  176. label_list
  177.     : label
  178.         | label_list ',' label
  179.         ;
  180.  
  181. label    : UNSIGNED_INTEGER
  182.         /* must be decimal integer in the range 0..9999 */
  183.     | ID
  184.         ;
  185.  
  186. const_decl_sect
  187.     : _CONST_ const_decl
  188.     | const_decl_sect const_decl
  189.     ;
  190.  
  191. type_decl_sect
  192.     : _TYPE_ type_decl
  193.     | type_decl_sect type_decl
  194.     ;
  195.  
  196. var_decl_sect
  197.     : _VAR_ var_decl
  198.     | var_decl_sect var_decl
  199.     ;
  200.  
  201. /* Interface declaration sections: */
  202.  
  203. /* These appear instead of normal declaration sections in the interface
  204.    part of a unit. The difference is that there are no label declarations
  205.    and for procedures and functions only the headings are given. */
  206.  
  207. int_decl_sect_list
  208.     : /* empty */
  209.     | int_decl_sect_list int_decl_sect
  210.     ;
  211.  
  212. int_decl_sect
  213.     : const_decl_sect
  214.     | type_decl_sect
  215.     | var_decl_sect
  216.     | proc_heading
  217.     | func_heading
  218.     ;
  219.  
  220. /* Constant declarations: */
  221.  
  222. const_decl
  223.     : ID '=' const ';'
  224.         | ID ':' type '=' typed_const ';'
  225.         ;
  226.  
  227. const    : unsigned_number
  228.     | sign unsigned_number
  229.         | ID
  230.         | sign ID
  231.         | STRING_CONST
  232.     ;
  233.  
  234. unsigned_number
  235.     : UNSIGNED_INTEGER
  236.         | UNSIGNED_REAL
  237.         ;
  238.  
  239. sign    : '+' | '-'
  240.     ;
  241.  
  242. typed_const
  243.     : const
  244.     | array_const
  245.     | record_const
  246.         | set_const
  247.     ;
  248.  
  249. array_const
  250.     : '(' typed_const_list ')'
  251.     ;
  252.  
  253. typed_const_list
  254.     : typed_const
  255.     | typed_const_list ',' typed_const
  256.     ;
  257.  
  258. record_const
  259.     : '(' const_field_list ')'
  260.     ;
  261.  
  262. const_field_list
  263.     : const_field
  264.     | const_field_list ',' const_field
  265.     ;
  266.  
  267. const_field
  268.     : ID ':' typed_const
  269.     ;
  270.  
  271. set_const
  272.     : '[' const_elem_list ']'
  273.         ;
  274.  
  275. const_elem_list
  276.     : /* empty */
  277.         | const_elem_list1
  278.         ;
  279.  
  280. const_elem_list1
  281.     : const_elem
  282.     | const_elem_list1 ',' const_elem
  283.     ;
  284.  
  285. const_elem
  286.     : const
  287.     | const '..' const
  288.     ;
  289.  
  290. /* Type declarations: */
  291.  
  292. type_decl
  293.     : ID '=' type ';'
  294.     ;
  295.  
  296. type    : simple_type
  297.     | pointer_type
  298.         | structured_type
  299.         | string_type
  300.         ;
  301.  
  302. simple_type
  303.     : ID
  304.     | const '..' const    /* subrange */
  305.     | '(' id_list ')'    /* enumeration */
  306.     ;
  307.  
  308. pointer_type
  309.     : '^' ID
  310.     ;
  311.  
  312. structured_type
  313.     : unpacked_structured_type
  314.         | _PACKED_ unpacked_structured_type
  315.         ;
  316.  
  317. unpacked_structured_type
  318.     : array_type
  319.     | record_type
  320.     | set_type
  321.     | file_type
  322.     ;
  323.  
  324. array_type
  325.     : _ARRAY_ '[' simple_type_list ']' _OF_ type
  326.     ;
  327.  
  328. simple_type_list
  329.     : simple_type
  330.     | simple_type_list ',' simple_type
  331.     ;
  332.  
  333. record_type
  334.     : _RECORD_ field_list _END_
  335.     ;
  336.  
  337. field_list
  338.     : fixed_part
  339.     | variant_part
  340.     | fixed_part ';' variant_part
  341.     ;
  342.  
  343. fixed_part
  344.     : record_section
  345.     | fixed_part ';' record_section
  346.     ;
  347.  
  348. record_section
  349.     : /* empty */
  350.     | id_list ':' type
  351.     ;
  352.  
  353. variant_part
  354.     : _CASE_ tag_field _OF_ variant_list
  355.     ;
  356.  
  357. tag_field
  358.     : ID
  359.     | ID ':' ID
  360.     ;
  361.  
  362. variant_list
  363.     : variant
  364.     | variant_list ';' variant
  365.     ;
  366.  
  367. variant    : /* empty */
  368.     | case_tag_list ':' '(' field_list ')'
  369.     ;
  370.  
  371. case_tag_list
  372.     : const
  373.         | case_tag_list ',' const
  374.         ;
  375.  
  376. set_type
  377.     : _SET_ _OF_ simple_type
  378.     ;
  379.  
  380. file_type
  381.     : _FILE_ _OF_ type
  382.     | _FILE_
  383.     ;
  384.  
  385. string_type
  386.     : _STRING_
  387.     | _STRING_ '[' const ']'
  388.     ;
  389.  
  390. /* Variable declarations: */
  391.  
  392. var_decl
  393.     : id_list ':' type absolute_clause ';'
  394.     ;
  395.  
  396. absolute_clause
  397.     : /* empty */
  398.         | _ABSOLUTE_ UNSIGNED_INTEGER ':' UNSIGNED_INTEGER
  399.         | _ABSOLUTE_ ID
  400.         ;
  401.  
  402. /* Procedure and function declarations: */
  403.  
  404. proc_decl
  405.     : proc_heading proc_block ';'
  406.     ;
  407.  
  408. func_decl
  409.     : func_heading proc_block ';'
  410.     ;
  411.  
  412. proc_heading
  413.     : _PROCEDURE_ ID fp_list ';'
  414.     ;
  415.  
  416. func_heading
  417.     : _FUNCTION_ ID fp_list ':' fptype ';'
  418.     ;
  419.  
  420. proc_block             /* omitted inline and interrupt */
  421.     : block
  422.     | _EXTERNAL_
  423.     | _FORWARD_
  424.     ;
  425.  
  426. fp_list : /* empty */
  427.     | '(' fp_sect_list ')'
  428.     ;
  429.  
  430. fp_sect_list
  431.     : fp_sect
  432.     | fp_sect_list ';' fp_sect
  433.     ;
  434.  
  435. fp_sect    : id_list ':' fptype
  436.     | _VAR_ id_list ':' fptype
  437.     | _VAR_ id_list
  438.     ;
  439.  
  440. fptype    : ID
  441.     | _STRING_
  442.     ;
  443.  
  444. /* Statements: */
  445.  
  446. stmt    : unlabelled_stmt
  447.     | label ':' unlabelled_stmt
  448.         ;
  449.  
  450. unlabelled_stmt
  451.     : /* empty */
  452.     | assignment
  453.     | proc_call
  454.     | goto_stmt
  455.     | compound_stmt
  456.     | if_stmt
  457.     | case_stmt
  458.     | repeat_stmt
  459.     | while_stmt
  460.     | for_stmt
  461.     | with_stmt
  462.     ;
  463.  
  464. assignment
  465.     : variable ':=' expr
  466.     ;
  467.  
  468. proc_call
  469.     : ID param_list
  470.     ;
  471.  
  472. param_list
  473.     : /* empty */
  474.     | '(' expr_list ')'
  475.     ;
  476.  
  477. expr_list
  478.     : expr
  479.     | expr_list ',' expr
  480.     ;
  481.  
  482. goto_stmt
  483.     : _GOTO_ label
  484.     ;
  485.  
  486. compound_stmt
  487.     : _BEGIN_ stmt_list _END_
  488.     ;
  489.  
  490. stmt_list
  491.     : stmt
  492.     | stmt_list ';' stmt
  493.     ;
  494.  
  495. if_stmt    : _IF_ expr _THEN_ stmt
  496.     | _IF_ expr _THEN_ stmt _ELSE_ stmt
  497.     ;
  498.  
  499. case_stmt
  500.     : _CASE_ expr _OF_ case_list else_case _END_
  501.     ;
  502.  
  503. case_list
  504.     : case
  505.     | case_list ';' case
  506.     ;
  507.  
  508. case    : /* empty */
  509.     | case_label_list ':' stmt
  510.     ;
  511.  
  512. case_label_list
  513.     : case_label
  514.         | case_label_list ',' case_label
  515.         ;
  516.  
  517. case_label
  518.     : const
  519.         | const '..' const
  520.         ;
  521.  
  522. else_case
  523.     : /* empty */
  524.     | _ELSE_ stmt
  525.     | _ELSE_ stmt ';'
  526.     ;
  527.  
  528. repeat_stmt
  529.     : _REPEAT_ stmt_list _UNTIL_ expr
  530.     ;
  531.  
  532. while_stmt
  533.     : _WHILE_ expr _DO_ stmt
  534.     ;
  535.  
  536. for_stmt
  537.     : _FOR_ ID ':=' expr _TO_ expr _DO_ stmt
  538.     | _FOR_ ID ':=' expr _DOWNTO_ expr _DO_ stmt
  539.     ;
  540.  
  541. with_stmt
  542.     : _WITH_ variable_list _DO_ stmt
  543.     ;
  544.  
  545. variable_list
  546.     : variable
  547.         | variable_list ',' variable
  548.         ;
  549.  
  550. /* Variables: */
  551.  
  552. variable
  553.     : ID
  554.     | variable '[' expr_list ']'        /* array component */
  555.     | variable '.' ID            /* record field */
  556.         | variable '^'                /* pointer value */
  557.     | ID '(' variable ')'                /* type cast */
  558.     ;
  559.  
  560. /* Expressions: */
  561.  
  562. expr    : simple_expr
  563.     | simple_expr relop simple_expr
  564.         ;
  565.  
  566. relop    : '=' | '<>' | '<' | '>' | '<=' | '>=' | _IN_
  567.         ;
  568.  
  569. simple_expr
  570.     : term
  571.         | sign term
  572.         | simple_expr addop term
  573.         ;
  574.  
  575. addop    : '+' | '-' | _OR_ | _XOR_
  576.     ;
  577.  
  578. term    : factor
  579.     | term mulop factor
  580.         ;
  581.  
  582. mulop    : '*' | '/' | _DIV_ | _MOD_ | _SHL_ | _SHR_
  583.     ;
  584.  
  585. /* Parameterless function calls, and function calls looking like type
  586.    casts are caught as variables. */
  587.  
  588. factor    : variable
  589.     | UNSIGNED_INTEGER
  590.         | UNSIGNED_REAL
  591.         | STRING_CONST
  592.         | '[' elem_list ']'
  593.         | _NIL_
  594.         | '@' variable
  595.         | '(' expr ')'
  596.         | ID '(' expr_list ')'
  597.         | _NOT_ factor
  598.         ;
  599.  
  600. elem_list
  601.     : /* empty */
  602.         | elem_list1
  603.         ;
  604.  
  605. elem_list1
  606.     : elem
  607.     | elem_list1 ',' elem
  608.     ;
  609.  
  610. elem    : expr
  611.     | expr '..' expr
  612.     ;
  613.  
  614.